package com.lap.auth.adapter.driving.persistence.menu.repository;

import com.lap.auth.adapter.driving.persistence.menu.MenuCache;
import com.lap.auth.adapter.driving.persistence.menu.MenuConverter;
import com.lap.auth.adapter.driving.persistence.menu.mapper.MenuMapper;
import com.lap.auth.adapter.driving.persistence.menu.po.MenuPo;
import com.lap.auth.domain.menu.Menu;
import com.lap.auth.domain.menu.repository.MenuRepository;
import com.lap.framework.exception.OptimisticLockingFailureException;
import java.util.List;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Repository;

@RequiredArgsConstructor
@Repository
public class MenuRepositoryImpl implements MenuRepository {

  private final MenuConverter converter;
  private final MenuMapper menuMapper;

  @CacheEvict(
      value = {MenuCache.MENU},
      allEntries = true)
  @Override
  public Integer save(Menu menu) {
    MenuPo menuPo = converter.toPo(menu);
    if (menu.isNew()) {
      menuMapper.insert(menuPo);
    } else {
      int affectedRows = menuMapper.updateById(menuPo);
      if (affectedRows < 1) {
        throw new OptimisticLockingFailureException();
      }
    }
    return menuPo.getId();
  }

  @CacheEvict(
      value = {MenuCache.MENU, MenuCache.MENU_OPT},
      allEntries = true)
  @Override
  public void deleteById(Integer id) {
    menuMapper.deleteById(id);
  }

  @Override
  public Optional<Menu> findById(Integer id) {
    MenuPo menuPo = menuMapper.selectById(id);
    return Optional.ofNullable(converter.toDomain(menuPo));
  }

  @Override
  public List<Menu> findList() {
    return converter.toDomains(menuMapper.selectList());
  }

  @Override
  public List<Menu> findByPid(Integer id) {
    return converter.toDomains(menuMapper.selectByPid(id));
  }

  @Cacheable(
      value = MenuCache.MENU,
      key = "T(com.lap.auth.domain.shared.tools.CacheKeyUtil).generateKey(#roleIds)")
  @Override
  public List<Menu> findMenuByRoleIds(List<Integer> roleIds) {
    List<MenuPo> list = menuMapper.selectByRoleIds(roleIds);
    return converter.toDomains(list);
  }

  @Cacheable(
      value = MenuCache.MENU_OPT,
      key = "T(com.lap.auth.domain.shared.tools.CacheKeyUtil).generateKey(#roleIds)")
  @Override
  public List<String> findOptionsByRoleIds(List<Integer> roleIds) {
    return menuMapper.selectPermCodeByRoleIds(roleIds);
  }
}
